/**
 * User控制器模块
 * 
 */

const express = require("express");

const util = require("../common/util");

/**
 * @typedef {UserDB}
 */
const UserDB = require("../model/sqlite/user");
const config = require("../common/config");

/**
 * 获取用户信息
 * @param {express.Request} req 请求
 * @param {express.Response} res 响应
 */
function find(req, res) {
    (async function () { 
        let db = UserDB.getInstance();
        await db.connect();
        let result = await db.find(req.params.id);
        // await db.close();
        result.fullAvator = config.serverUrl + "/" + result.avatar;
        result.roleName = (() => {
            if (result.role === 1) {
                return "管理用户组";
            } else if (result.role === 2) {
                return "普通用户组";
            }
        })();
        util.logFormat(`获取【${req.params.id}】用户信息%O`, result);
        res.json(util.FormatJSONData(200, `获取用户信息【${req.params.id}】`, result));
    })().catch(err => {
        util.err(err);
        res.json(util.FormatJSONData(500,"服务器发生意外情况，无法完成请求！"));
    });
}

/**
 * 获取用户信息列表
 * @param {express.Request} req 请求
 * @param {express.Response} res 响应
 */
function findAll(req, res) {
    (async function () { 
        // 1.处理输入的数据
        // FIXME:输入数据的正确性校验，一致性校验，完整性校验
        let limit = req.query.limit ? req.query.limit : -1;
        let offset = req.query.offset ? req.query.offset : -1;
        // 2.访问数据
        let db = UserDB.getInstance();
        await db.connect();
        let result = await db.findAll(limit,offset);
        // await db.close();

        // 3.输出数据
        util.logFormat(`获取【limit=${limit}&offset=${offset}】用户信息%O`, result);
        res.json(util.FormatJSONData(200, `获取用户信息列表`, result));
    })().catch(err => {
        util.err(err);
        res.json(util.FormatJSONData(500,"服务器发生意外情况，无法完成请求！"));
    });
}

/**
 * 新增用户信息
 * @param {express.Request} req 请求
 * @param {express.Response} res 响应
 */
function add(req, res) {
    (async function () { 
        //FIXME:req.body的数据安全性校验
        let user = {
            username:req.body.username,
            password:util.md5pwd(req.body.password),
            nickname:req.body.nickname,
            truename:req.body.truename,
            avatar:req.body.avatar,
            role:req.body.role,
            lastLoginTime:0,
            lastLoginIP: "never login",
            createdTime:Date.now(),
            createdIP:util.getReqRemoteIP(req),
            updatedTime:Date.now()
        };
        let db = UserDB.getInstance();
        await db.connect();
        let result = await db.add(user);
        // await db.close();
        util.log(`新增用户信息：lastID->${result}`);
        res.json(util.FormatJSONData(201, `新增用户信息`, { lastID: result }));
    })().catch(err => {
        util.err(err);
        res.json(util.FormatJSONData(500,"服务器发生意外情况，无法完成请求！"));
    });
}

/**
 * 更新用户信息
 * @param {express.Request} req 请求
 * @param {express.Response} res 响应
 */
function update(req, res) {
    (async function () { 
        //FIXME:req.body的数据安全性校验
        let user = {
            id:req.params.id,
            username:req.body.username,
            password:util.md5pwd(req.body.password),
            nickname:req.body.nickname,
            truename:req.body.truename,
            avatar:req.body.avatar,
            role:req.body.role,
            updatedTime:Date.now()
        };
        let db = UserDB.getInstance();
        await db.connect();
        let result = await db.update(user);
        // await db.close();
        util.log(`更新用户信息：changes->${result}`);
        res.json(util.FormatJSONData(200, `更新用户信息`, { changes: result }));
    })().catch(err => {
        util.err(err);
        res.json(util.FormatJSONData(500,"服务器发生意外情况，无法完成请求！"));
    });
}

/**
 * 删除用户信息
 * @param {express.Request} req 请求
 * @param {express.Response} res 响应
 */
function remove(req, res) {
    (async function () { 
        // FIXME:数据合法性校验
        let userId = req.params.id;
        let db = UserDB.getInstance();
        await db.connect();
        let result = await db.remove(userId);
        // await db.close();
        util.log(`删除用户信息：changes->${result}`);
        res.json(util.FormatJSONData(204, `删除用户信息`, { changes: result }));
    })().catch(err => {
        util.err(err);
        res.json(util.FormatJSONData(500,"服务器发生意外情况，无法完成请求！"));
    });
}

/**
 * 获取用户总数
 * @param {express.Request} req 请求
 * @param {express.Response} res 响应
 */
function getCount(req, res) {
    (async function () { 
        // FIXME:数据合法性校验
        let db = UserDB.getInstance();
        await db.connect();
        let result = await db.getCount();
        // await db.close();
        util.log(`获取用户总数：${result}`);
        res.json(util.FormatJSONData(200, `获取用户总数`, result));
    })().catch(err => {
        util.err(err);
        res.json(util.FormatJSONData(500,"服务器发生意外情况，无法完成请求！"));
    });
}

/**
 * 按关键字搜索用户信息
 * @param {express.Request} req 请求
 * @param {express.Response} res 响应
 */
function search(req, res) {
    (async function () { 
        // 1.处理输入的数据
        // FIXME:输入数据的正确性校验，一致性校验，完整性校验
        let q = req.query.q;
        let limit = req.query.limit ? req.query.limit : -1;
        let offset = req.query.offset ? req.query.offset : -1;
        // 2.访问数据
        let db = UserDB.getInstance();
        await db.connect();
        let result = await db.search(q, limit, offset);
        // await db.close();

        // 3.输出数据
        util.logFormat(`获取关键字为【${q}】【limit=${limit}&offset=${offset}】用户信息%O`, result);
        res.json(util.FormatJSONData(200, `获取指定关键字的用户信息列表`, result));
    })().catch(err => {
        util.err(err);
        res.json(util.FormatJSONData(500,"服务器发生意外情况，无法完成请求！"));
    });
}

/**
 * 注册用户
 * @param {express.Request} req 请求
 * @param {express.Response} res 响应
 */
function register(req, res) {
    (async function () { 
        //FIXME:req.body的数据安全性校验
        let user = {
            username:req.body.username,
            password:util.md5pwd(req.body.password),
            nickname:req.body.nickname ? req.body.nickname : "",
            truename:req.body.truename ? req.body.truename : "",
            avatar:req.body.avatar ? req.body.avatar : "",
            role:2,
            lastLoginTime:0,
            lastLoginIP: "never login",
            createdTime:Date.now(),
            createdIP:util.getReqRemoteIP(req),
            updatedTime:Date.now()
        };
        let db = UserDB.getInstance();
        await db.connect();
        let result = await db.register(user);
        // await db.close();
        util.log(`注册用户信息：lastID->${result}`);
        res.json(util.FormatJSONData(201, `注册用户`, { lastID: result }));
    })().catch(err => {
        util.err(err);
        res.json(util.FormatJSONData(500,"服务器发生意外情况，无法完成请求！"));
    });
}

/**
 * 用户登录
 * @param {express.Request} req 请求
 * @param {express.Response} res 响应
 */
function login(req, res) {
    (async function () {
        //FIXME:req.body的数据安全性校验
        let username = req.body.username;
        let password = util.md5pwd(req.body.password);

        let msg = `用户【${username}】登录失败，请检查用户名和密码`;
        let data = { loginStatus: "failed" };

        let db = UserDB.getInstance();
        await db.connect();
        let result = await db.login(username, password);
        if (result) {
            msg = `用户【${username}】登录成功`;
            data = {
                loginStatus: "success",
                userId: result.id,
                username: result.username,
                nickname: result.nickname,
                truename: result.truename,
                role: result.role,
            };
            let lastLogin = {
                time: Date.now(),
                ip: util.getReqRemoteIP(req),
            };
            await db.touch(username, lastLogin);
            //使用session保存登录状态
            req.session.isLogin = true;
            req.session.user = result;
        }
        // await db.close();
        util.logFormat(`用户【${username}】登录，用户信息%O`, result);
        res.json(util.FormatJSONData(200, msg, data));
    })().catch(err => {
        util.err(err);
        res.json(util.FormatJSONData(500,"服务器发生意外情况，无法完成请求！"));
    });
}

/**
 * 用户退出
 * @param {express.Request} req 请求
 * @param {express.Response} res 响应
 */
function logout(req, res) {
    if (req.session.user) {
        let username = req.session.user.username;
        req.session.destroy(err => util.log(err));

        util.log(`用户【${username}】退出，用户session值【${req.session}】`);
        res.json(util.FormatJSONData(200, `用户【${username}】退出系统`,
            { logoutStatus: "success" }
        ));
    } else {
        res.json(util.FormatJSONData(200, `非正常访问路径`));
    }
}

/**
 * 修改个人信息
 * @param {express.Request} req 请求
 * @param {express.Response} res 响应
 */
function changeInfo(req, res) {
    (async function () { 
        //FIXME:req.body的数据安全性校验
        let info = {
            nickname:req.body.nickname,
            truename:req.body.truename,
            avatar:req.body.avatar,
        };
        let id = req.session.user.id;

        let db = UserDB.getInstance();
        await db.connect();
        let result = await db.changeInfo(id, info);
        // await db.close();
        util.log(`修改个人信息：changes->${result}`);
        res.json(util.FormatJSONData(200, `修改个人信息成功`, { changes: result }));
    })().catch(err => {
        util.err(err);
        res.json(util.FormatJSONData(500,"服务器发生意外情况，无法完成请求！"));
    });
}

/**
 * 修改用户密码
 * @param {express.Request} req 请求
 * @param {express.Response} res 响应
 */
function changePassword(req, res) {
    (async function () { 
        //FIXME:req.body的数据安全性校验
        let password = util.md5pwd(req.body.password);
        let id = req.session.user.id;

        let db = UserDB.getInstance();
        await db.connect();
        let result = await db.changePassword(id, password);
        // await db.close();
        util.log(`修改用户密码：changes->${result}`);
        res.json(util.FormatJSONData(200, `修改个人密码成功`, { changes: result }));
    })().catch(err => {
        util.err(err);
        res.json(util.FormatJSONData(500,"服务器发生意外情况，无法完成请求！"));
    });
}

/**
 * 重置用户密码
 * @param {express.Request} req 请求
 * @param {express.Response} res 响应
 */
function resetPassword(req, res) {
    (async function () { 
        //FIXME:req.body的数据安全性校验
        let password = util.md5pwd("123456");
        let id = req.params.id;

        let db = UserDB.getInstance();
        await db.connect();
        let result = await db.changePassword(id, password);
        // await db.close();
        util.log(`重置用户密码：changes->${result}`);
        res.json(util.FormatJSONData(200, `用户重置密码成功`, { changes: result }));
    })().catch(err => {
        util.err(err);
        res.json(util.FormatJSONData(500,"服务器发生意外情况，无法完成请求！"));
    });
}

module.exports = {
    find,
    findAll,
    add,
    update,
    remove,
    getCount,
    search,
    register,
    login,
    logout,
    changeInfo,
    changePassword,
    resetPassword,
};